/*
 * 
 *  This file is part of Sourceprojects.org Lycia Copyright 2010 noctarius
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 * 
 */
package org.sourceprojects.lycia.fluent;

import javax.xml.XMLConstants;

import org.sourceprojects.lycia.Delegate;
import org.sourceprojects.lycia.Generator;
import org.sourceprojects.lycia.LyciaConfigurator;
import org.sourceprojects.lycia.LyciaParser;
import org.sourceprojects.lycia.annotations.Namespace;
import org.sourceprojects.lycia.annotations.Tag;
import org.sourceprojects.lycia.annotations.Validator;
import org.sourceprojects.lycia.internal.configuration.TagInnerImpl;
import org.sourceprojects.lycia.internal.configuration.XPathInnerImpl;
import org.sourceprojects.lycia.internal.configuration.TagConfigurationUtils.MethodDefinition;

class XPathEventBuilder<B> implements EventBuilder<B> {
	private final String expression;
	private final NamespacesBuilder namespacesBuilder;
	private final MethodBuilder methodBuilder;
	private final ValidationsBuilder validationsBuilder;

	XPathEventBuilder(final String expression,
			final NamespacesBuilder namespacesBuilder,
			final MethodBuilder methodBuilder,
			final ValidationsBuilder validationsBuilder) {

		this.expression = expression;
		this.namespacesBuilder = namespacesBuilder;
		this.methodBuilder = methodBuilder;
		this.validationsBuilder = validationsBuilder;
	}

	public BuildReturn<B> build(final LyciaConfigurator<B> configurator,
			final LyciaParser<B> lyciaParser) {

		final Generator<B> generator = configurator.getGeneratorFactory()
				.newInstance(configurator.getGenerationStrategy());

		Validator[] validators;
		if (validationsBuilder != null) {
			validators = validationsBuilder.build();
		} else {
			validators = new Validator[0];
		}

		Namespace[] namespaces;
		if (namespacesBuilder != null) {
			namespaces = namespacesBuilder.build();
		} else {
			namespaces = new Namespace[0];
		}

		final Tag tag = new TagInnerImpl("*", XMLConstants.NULL_NS_URI,
				new XPathInnerImpl(expression, namespaces), false, validators);

		final MethodDefinition definition = new MethodDefinition(methodBuilder
				.getMethod(), tag);

		final Delegate<B> delegate = generator.generate(methodBuilder
				.getParser(), definition, lyciaParser);

		return new BuildReturn<B>(delegate, tag, XMLConstants.NULL_NS_URI);
	}

	static class BuildReturn<B> {
		final Delegate<B> delegate;
		final Tag tag;
		final String namespaceURI;

		private BuildReturn(final Delegate<B> delegate, final Tag tag,
				final String namespaceURI) {
			this.delegate = delegate;
			this.tag = tag;
			this.namespaceURI = namespaceURI;
		}
	}
}
